package study.rpc.dubbo.provider.support.filter;

import com.google.common.base.Joiner;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.RpcException;

import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Activate(group = CommonConstants.PROVIDER, order = 1)
public class WatchDogFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        //
        Stopwatch watch = Stopwatch.createStarted();
        log.info(">>>>>> watchdog filter");
        //
        String canonicalName = invoker.getInterface().getCanonicalName();
        String methodName = invocation.getMethodName();
        String fullMethod = Joiner.on(".").join(canonicalName, methodName);
        URL url = invoker.getUrl();
        //LOGGER.info("url={}", url);
        //
        Result result;
        try {
            //调用
            result = invoker.invoke(invocation);
            //异常
            if (result.hasException()) {
                Result rpcResult = toRpcResult(result);
                Map<String, Object> data = Maps.newHashMap();
                data.put("code", "9999");
                data.put("desc", rpcResult.getException().getMessage());
                //
                rpcResult.setException(null);
                rpcResult.setValue(data);
            }
        } catch (RpcException ex) {
            throw ex;
        } finally {
            log.info(">>>>>> {} cost time [{}] ms", fullMethod, watch.elapsed(TimeUnit.MILLISECONDS));
        }
        return result;
    }

    private Result toRpcResult(Result result) {
        return (Result) result;
    }
}
